package com.jketing.controller.ams;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jketing.Constants;
import com.jketing.entity.ams.base.Employee;
import com.jketing.entity.ams.sys.Account;
import com.jketing.entity.ams.sys.Function;
import com.jketing.service.ams.base.EmployeeService;
import com.jketing.service.ams.sys.AccountService;
import com.jketing.service.ams.sys.RoleService;

/**
 * EntryController 入口请求处理
 * 
 * @author  李荣华
 * @version v1.0
 * @date    2017-11-30
 * @since   Spring-mvc 4.3.8
 */
@Controller
public class EntryController {
	
	/**
	 *  service 账号服务层引用
	 */
	@Autowired
	private AccountService accountService;	
	/**
	 *  service 角色服务层引用
	 */
	@Autowired
	private RoleService roleService;
	/**
	 *  service 角色服务层引用
	 */
	@Autowired
	private EmployeeService employeeService;
	
	/**
	 *  positionSelect	打开地图定位
	 *  
	 *  @param	String	addr 定位地址
	 *  
	 *  @return	String	返回页面路径
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value="/positionSelect",method=RequestMethod.GET)
	public String positionSelect(){
		return "dialog/map/positionSelect";
	}
	
	/**
	 * 异步请求树型子节点，返回json数据
	 * 
	 * produces="application/json; charset=utf-8" 解决单方法返回中文乱码问题
	 * 
	 * @return 无返回，直接向response里写数据
	 */
	@RequestMapping(value="/getCurrentAccount",method=RequestMethod.GET)
	@ResponseBody
	public Account getCurrentAccount(){
		Account account = null;
		Subject subject = SecurityUtils.getSubject();
		if (subject.isAuthenticated()) {
			account = (Account)subject.getPrincipal();
		}
		return account;
	}
	
	/**
	 * login 客户端登录
	 * @return
	 */
	@RequestMapping("/ClientLogin")
	@ResponseBody
	public String logout(@RequestParam("loginName") String loginName, 
						 @RequestParam("password") String password,
						 HttpSession session){
		String seesionId = session.getId();
		System.out.println("-------------------------------------"+seesionId);
		Subject subject = SecurityUtils.getSubject();		
		if (!subject.isAuthenticated()) {
        	// 把用户名和密码封装为 UsernamePasswordToken 对象
            UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
            try {
            	// 执行登录. 
            	subject.login(token);
            	System.out.println("++++++++++++++++++++++++++++++++++++++++++:"+seesionId);
            } 
            // 若没有指定的账户, 则 shiro 将会抛出 UnknownAccountException 异常. 
            catch (UnknownAccountException uae) {
            	return "UnknownAccount"; 
            } 
            // 若账户存在, 但密码不匹配, 则 shiro 会抛出 IncorrectCredentialsException 异常。 
            catch (IncorrectCredentialsException ice) {
            	return "PasswordError"; 
            } 
            // 用户被锁定的异常 LockedAccountException
            catch (LockedAccountException lae) {
            	return "LockedAccount"; 
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            // 所有认证时异常的父类. 
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            	return "ServerLoginError"; 
            }
        }
		return seesionId;
	}
	
	/**
	 *  login 登录
	 *  
	 *  @param String loginName 登录名
	 *  @param String password 密码
	 *  
	 *  @return	ModelAndView 返回页面
	 */
	@RequestMapping("/login")
	public String login(@RequestParam("loginName") String loginName, 
						@RequestParam("password") String password,
						Map<String, Object> map,
						HttpSession session){
		String seesionId = session.getId();
		System.out.println("-------------------------------------"+seesionId);
		Subject subject = SecurityUtils.getSubject();		
		if (!subject.isAuthenticated()) {
        	// 把用户名和密码封装为 UsernamePasswordToken 对象
            UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
            // rememberme  打开报错
            //token.setRememberMe(true);            
            try {
            	// 执行登录. 
            	subject.login(token);
            	System.out.println("++++++++++++++++++++++++++++++++++++++++++:"+seesionId);
            	Account account = (Account)subject.getPrincipal();
            	session.setAttribute(Constants.SESSION_ACCOUNT, account);            	
            	session.setAttribute(Constants.SESSION_ROLE, account.getDefaultRole());
            	session.setAttribute(Constants.SESSION_THEMESNAME, account.getThemes());
            	List<Function> menu = roleService.getMenu(account.getDefaultRole().getId());
            	session.setAttribute(Constants.SESSION_MENU,menu );				
            	session.setAttribute(Constants.SESSION_ROLELIST, accountService.getRoles(account.getId()));
            	SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E ");   
		        String loginDate = dateFormat.format(new Date());
				session.setAttribute(Constants.SESSION_LOGINDATE, loginDate);
				if("normalAccount".equals(account.getType())) {
					Employee employee = employeeService.findOne(account.getPerson().getId());
					session.setAttribute(Constants.SESSION_TYPENAME, "职工");
					session.setAttribute(Constants.SESSION_MAN, employee);
					session.setAttribute(Constants.SESSION_ORG, employee.getOrgan());
				}else if("adminAccount".equals(account.getType())) {
					session.setAttribute(Constants.SESSION_TYPENAME, "管理员");
					session.setAttribute(Constants.SESSION_MAN, account.getPerson());
				}else {
					session.setAttribute(Constants.SESSION_TYPENAME, "用户");
					session.setAttribute(Constants.SESSION_MAN, account.getPerson());
				}
				seesionId = session.getId();
				
            } 
            // 若没有指定的账户, 则 shiro 将会抛出 UnknownAccountException 异常. 
            catch (UnknownAccountException uae) {
            	map.put("loginName", loginName); 
            	map.put("password", password);
            	map.put("loginInfo", uae.getMessage());
            	return "forward:/login.jsp"; 
            } 
            // 若账户存在, 但密码不匹配, 则 shiro 会抛出 IncorrectCredentialsException 异常。 
            catch (IncorrectCredentialsException ice) {
            	map.put("loginName", loginName); 
            	map.put("password", password);
            	map.put("loginInfo", "密码错误！");
            	return "forward:/login.jsp"; 
            } 
            // 用户被锁定的异常 LockedAccountException
            catch (LockedAccountException lae) {
            	map.put("loginName", loginName); 
            	map.put("password", password);
            	map.put("loginInfo", lae.getMessage());
            	return "forward:/login.jsp"; 
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            // 所有认证时异常的父类. 
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            	map.put("loginName", loginName); 
            	map.put("password", password);
            	map.put("loginInfo", ae.getMessage());
            	return "forward:/login.jsp"; 
            }
        }
		return "redirect:/main";
	}
	
	/**
	 * 切换角色
	 * @return
	 */
	@RequestMapping(value="/changeRole",method=RequestMethod.GET)
	@ResponseBody
	public String changeRole(String roleId,HttpSession session){
		Account account = (Account)session.getAttribute(Constants.SESSION_ACCOUNT);		
		account.setDefaultRole(roleService.findOne(roleId));
		accountService.saveAndFlush(account);
		return Constants.SUCCESS;
	}
}
